package com.cfpamf.athean.rabbit.mq.plus.repository.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cfpamf.athean.rabbit.mq.plus.common.constant.BusinessConstants;
import com.cfpamf.athean.rabbit.mq.plus.common.enums.ProcessStatusEnum;
import com.cfpamf.athean.rabbit.mq.plus.domain.po.RabbitMqPlusConsumerTaskPO;
import com.cfpamf.athean.rabbit.mq.plus.mapper.RabbitMqPlusConsumerTaskMapper;
import com.cfpamf.athean.rabbit.mq.plus.repository.RabbitMqPlusConsumerTaskRepository;
import com.cfpamf.athena.utils.Assert;
import com.cfpamf.athena.utils.DateUtils;
import com.cfpamf.athena.utils.Tools;

import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * rabbitMqPlus消费任务表 服务实现类
 * </p>
 *
 * @author Andy（陈洪桥）
 * @since 2022-12-11 22:32:32
 */
@Slf4j
@Service
public class RabbitMqPlusConsumerTaskRepositoryImpl
    extends ServiceImpl<RabbitMqPlusConsumerTaskMapper, RabbitMqPlusConsumerTaskPO>
    implements RabbitMqPlusConsumerTaskRepository {

    @Resource
    private RabbitMqPlusConsumerTaskMapper rabbitMqPlusConsumerTaskMapper;

    @Override
    public RabbitMqPlusConsumerTaskPO selectOneByQueueNameAndConsumerTypeCode(String queueName,
        String consumerTypeCode) {
        if (Tools.isEmpty(queueName)) {
            return null;
        }
        if (Tools.isEmpty(consumerTypeCode)) {
            return null;
        }
        LambdaQueryWrapper<RabbitMqPlusConsumerTaskPO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(RabbitMqPlusConsumerTaskPO::getQueueName, queueName);
        queryWrapper.eq(RabbitMqPlusConsumerTaskPO::getConsumerTypeCode, consumerTypeCode);
        return super.getOne(queryWrapper, Boolean.TRUE);
    }

    @Override
    public boolean updateByQueueNameAndConsumerTypeCode(RabbitMqPlusConsumerTaskPO po) {
        Assert.notEmpty(po, "抱歉，更新消息任务对象条件为空，拒绝更新！");
        Assert.notEmpty(po.getQueueName(), "抱歉，更新消息任务对象条件queueName为空，拒绝更新！");
        Assert.notEmpty(po.getConsumerTypeCode(), "抱歉，更新消息任务对象条件consumerTypeCode为空，拒绝更新！");
        LambdaUpdateWrapper<RabbitMqPlusConsumerTaskPO> updateWrapper = Wrappers.lambdaUpdate();
        updateWrapper.eq(RabbitMqPlusConsumerTaskPO::getQueueName, po.getQueueName());
        updateWrapper.eq(RabbitMqPlusConsumerTaskPO::getConsumerTypeCode, po.getConsumerTypeCode());
        updateWrapper.ne(RabbitMqPlusConsumerTaskPO::getStatusCode, ProcessStatusEnum.DONE.getCode());
        return super.update(po, updateWrapper);
    }

    @Override
    public List<RabbitMqPlusConsumerTaskPO> queryTodoDataByStatus(List<Integer> status) {
        if (Tools.isEmpty(status)) {
            return null;
        }
        LambdaQueryWrapper<RabbitMqPlusConsumerTaskPO> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.in(RabbitMqPlusConsumerTaskPO::getStatusCode, status);
        queryWrapper.gt(RabbitMqPlusConsumerTaskPO::getMaxRetryCount, BusinessConstants.ZERO);
        queryWrapper.le(RabbitMqPlusConsumerTaskPO::getNextExecuteTime, DateUtils.currentTime());
        return super.list(queryWrapper);
    }

    @Override
    public boolean deleteInvalidDataByDay(int day) {
        if (log.isDebugEnabled()) {
            log.debug("[rabbitMqPlus]请检查 rabbitMqPlus.delete.invalid.data.day=[{}] 配置值小于=10，无效数据至少保留10天以上！", day);
        }
        Assert.isTrue(day >= 10, "抱歉，请检查 rabbitMqPlus.delete.invalid.data.day 配置值小于=10，无效数据至少保留10天以上！");
        Date deleteInvalidDataByDayTime = DateUtils.addDay(day);
        LambdaQueryWrapper<RabbitMqPlusConsumerTaskPO> deleteWrapper = Wrappers.lambdaQuery();
        deleteWrapper.eq(RabbitMqPlusConsumerTaskPO::getStatusCode, ProcessStatusEnum.DONE.getCode());
        deleteWrapper.gt(RabbitMqPlusConsumerTaskPO::getConsumerTime,DateUtils.convertDateToLocalDateTime(deleteInvalidDataByDayTime));
        int total = rabbitMqPlusConsumerTaskMapper.deleteByLimit5000(deleteWrapper);
        log.info("[rabbitMqPlus] {}天，无效消费者数据删除条数:{}", DateUtils.format(deleteInvalidDataByDayTime), total);
        return Boolean.TRUE;
    }
}
